#+TITLE: Common Lisp to Scheme translation
#+SUBTITLE: Help for translating the book's code to Scheme
#+TAGS: Scheme, Common Lisp
#+AUTHOR: Zelphir Kaltstahl
#+CREATOR: Emacs
#+LANGUAGE: English
#+EXCLUDE_TAGS: noexport, notexported
#+OPTIONS: ^:{} H:10 toc:2

* Common Lisp to Scheme translation

** Straight forward translations

- ~defun~ -> ~define~
- ~defvar~ -> ~define~ or ~let~
- ~setf~ -> ~define~ or ~let~
- ~function~ or ~#'~ -> nothing, no difference is made in referring to values or procedures, Scheme is a Lisp 1.
- ~mapcar~ -> ~map~
- ~funcall~ -> simply call the procedure, s-expr with procedure in the first place

** Others

*** NIL

In Common Lisp ~NIL~ is a defined symbol:

#+NAME: def-nil
#+BEGIN_SRC scheme :noweb yes :exports code :eval never-export
(define NIL '())
#+END_SRC

*** car

~car~ of an empty list in Common Lisp returns NIL, the empty list again. ~car~ in Scheme does not return the empty list, but raises an error. This means, that, for compatibility reasons, we have to write a little procedure, which acts like ~car~ from Common Lisp:

#+BEGIN_SRC scheme :noweb yes :exports code :eval never-export
<<def-nil>>

(define car/nil
  (lambda (possibly-empty-list)
    "In Common Lisp car of an empty list returns the empty list called NIL. In
Scheme it would be an error to call car on an empty list. We write a wrapper, to
avoid an error."
    (cond
     [(null? possibly-empty-list) NIL]
     [else (car possibly-empty-list)])))
#+END_SRC

*** rest

~rest~ in Common Lisp also returns ~NIL~, when called with the empty list as argument, so a wrapper is needed:

#+BEGIN_SRC scheme :noweb yes :exports code :eval never-export
<<def-nil>>

(define rest
  (lambda (lst)
    (cond
     [(null? lst) NIL]
     [else (cdr lst)])))
#+END_SRC

*** defparameter

A parameter is explained in the book as a binding, that usually does not chance, a constant. A change to it is explained as a change /to/ the program, not a change /by/ the program, in contrast to using ~defvar~.

Since in Scheme we usually try to avoid using assignment or ~set!~ anyway, we can get away with following a convention of naming constants with enclosing asterisks: ~*constant*~ and using ~define~.

*** assoc

In Common Lisp ~assoc~ returns ~NIL~, when there is no matching entry in the association list. In Scheme ~#f~ is returned instead. We write a wrapper:

#+BEGIN_SRC scheme :noweb yes :exports code :eval never-export
(use-modules
 ((srfi srfi-1) #:prefix srfi-1:))

<<def-nil>>

(define assoc
  (lambda (key alist)
    (let ([res (srfi-1:assoc key alist)])
      (cond
       [res res]
       [else NIL]))))
#+END_SRC


*** case

???
